#ifndef __OBJ_PARSER_H__
#define __OBJ_PARSER_H__
#include "mesh.h"
#include <string_view>
#include <charconv>
#include <filesystem>

class ObjParser {
public:
    static Mesh Parse(std::filesystem::path objPath);
private:
    static Mesh::TriangleIndex parseIndex(std::string_view);
    
    static Vec4f parseVertex(std::string_view value) {
        Vec4f vec = parseVec<Vec3f>(value, ' ');
        vec.w = 1.0f;
        return vec;
    }

    static Vec3f parseNormal(std::string_view value) { 
        return parseVec<Vec3f>(value, ' '); 
    }
    
    static TexCoord parseTexCoord(std::string_view value) { 
        return parseVec<Vec2f>(value, ' '); 
    }
    
    static Mesh::VertexIndex parseVertexIndex(std::string_view value) {
        return parseVec<Mesh::VertexIndex>(value, '/');
    }

public:
    template <class Vec>
    static Vec parseVec(std::string_view value, char token) {
        size_t currToken = 0;
        size_t nextToken = value.find(token) + 1;

        Vec vec;
        for (size_t i = 0; i < Vec::size; ++i) {
            std::from_chars(value.data() + currToken, value.data() + nextToken, vec[i]);

            currToken = nextToken;
            nextToken = value.find(token, currToken) + 1;
            if (nextToken == 0) {
                nextToken = value.size();
            }
        }
        return vec;
    }
};

#endif